package top.broncho.lottery.data

import android.app.Application
import android.util.SparseArray
import androidx.room.Room
import androidx.room.RoomDatabase
import retrofit2.Retrofit
import top.broncho.lottery.api.provideRetrofit
import top.broncho.lottery.db.DATABASE_NAME
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class RepositoryManager @Inject constructor(private val app: Application) : IRepositoryManager {

    private val retrofit: Retrofit by lazy { app.provideRetrofit() }
    private val retrofitServiceCache by lazy { SparseArray<Any>() }
    private val roomDatabaseCache by lazy { SparseArray<RoomDatabase>() }

    override fun <T> obtainRetrofitService(service: Class<T>): T {
        var retrofitService: T
        synchronized(retrofitServiceCache) {
            val value = retrofitServiceCache[service.name.hashCode()]
            if (value == null) {
                retrofitService = retrofit.create(service)
                retrofitServiceCache.put(service.name.hashCode(), retrofitService)
            } else {
                @Suppress("UNCHECKED_CAST")
                retrofitService = value as T
            }
        }
        return retrofitService
    }

    override fun <DB : RoomDatabase> obtainRoomDatabase(database: Class<DB>): DB {
        var roomDatabase: DB
        synchronized(roomDatabaseCache) {
            val value = roomDatabaseCache[database.name.hashCode()]
            if (value == null) {
                val builder =
                    Room.databaseBuilder(app, database, DATABASE_NAME)
                roomDatabase = builder.build()
                roomDatabaseCache.put(database.name.hashCode(), roomDatabase)
            } else {
                @Suppress("UNCHECKED_CAST")
                roomDatabase = value as DB
            }
        }
        return roomDatabase
    }

    override fun clearAllCache() {
        retrofitServiceCache.clear()
    }

}

